#ifndef __HIENC_PUBLIC_H__
#define __HIENC_PUBLIC_H__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdarg.h>
#include "enc_shrm.h"
#include "u/u_io.h"
#include "u/u_util.h"
#include "enc_version.h"

#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"     // rapidjson's DOM-style API
#include "rapidjson/prettywriter.h" // for stringify JSON
#include "rapidjson/pointer.h"

#define		ENC_APP_MST_VER   	0x10
#define		END_APP_SLV_VER   	0x20

#define		ENC_CFGPATH  		"/bwsc/cfg/"
#define 	HIENC_RAM_LOG_PATH	"/bwsc/ramfs/"
#define 	BWSC_BIN_PATH		"/bwsc/bin"
#define 	BWSC_DATA_PATH		"/bwsc/data"
#define 	BWSC_SCRIPT_PATH	"/bwsc/script"


#define		ENC_MST_CFG			"master.cfg"
#define 	ENC_SLV_CFG			"slave.cfg"

//format LOG print
#define BW_INFO(format, ...) \
		_enc_log("[info ] [%s %d:%s] " \
		format, \
		__FILE__, __LINE__, __func__, ##__VA_ARGS__)

#define BW_DEBUG(format, ...) \
		_enc_log("\033[0;32m[debug ] [%s %d:%s] " \
		format, \
		__FILE__, __LINE__, __func__, ##__VA_ARGS__)

#define BW_ERROR(format, ...)	\
		_enc_log("\033[0;31m[error] [%s %d:%s] " \
		format, \
		__FILE__, __LINE__, __func__, ##__VA_ARGS__)

#define BW_WARN(format, ...)	\
		_enc_log("\033[1;33m[warn ] [%s %d:%s] " \
		format, \
		__FILE__, __LINE__, __func__, ##__VA_ARGS__)

/*
#define BW_INFO(format, ...)	\
	do {	\
		struct timeval tv = { 0 };	\
		gettimeofday(&tv, NULL);	\
		time_t _time = tv.tv_sec;	\
		struct tm occurs = { 0 };	\
		localtime_r(&_time, &occurs);	\
		printf("[%04d-%02d-%02d %02u:%02u:%02u.%03ld] [%s %d:%s] " format, \
				(1900 + occurs.tm_year), (1 + occurs.tm_mon), occurs.tm_mday,	\
				occurs.tm_hour, occurs.tm_min, occurs.tm_sec, tv.tv_usec / 1000,	\
				__FILE__, __LINE__, __func__, ##__VA_ARGS__ );	\
	} while(0);
*/


#ifndef SAFE_CLOSE_FD
#define SAFE_CLOSE_FD(fd)	\
	if (fd >= 0) 	\
	{	\
		close(fd);	\
		fd = -1;	\
	}
#endif

#ifndef SAFE_DELETE_PTR
#define SAFE_DELETE_PTR(p)	\
	if (p)	\
	{	\
		delete p;	\
		p = NULL;	\
	}
#endif

#define SAFE_DELETE_ARRAY(p)	\
do { \
	if (p) { \
		delete []p;	\
		p = NULL;	\
	}	\
}while(0)

#ifndef SAFE_FREE_PTR
#define SAFE_FREE_PTR(p)	\
	if (p)	\
	{	\
		free(p);	\
		p = NULL;	\
	}
#endif

#ifndef SAFE_SEM_WAIT
#define SAFE_SEM_WAIT(sem)	\
	if (sem) \
	{	\
		sem_wait(sem);	\
	}
#endif

#ifndef SAFE_SEM_POST
#define SAFE_SEM_POST(sem)	\
	if (sem)	\
	{	\
		sem_post(sem);	\
	}
#endif

//for global sem veraible
extern sem_t*         g_shrmsem;
extern sem_t*         g_devsem;
extern sem_t*         g_logsem;

//for global variable
extern pENC_DEVSET_MASTER  	g_encset_mst;
extern pENC_DEVSET_SLAVE  	g_encset_slv;
extern char           		g_cfgpath[MAX_PATH];
extern int 					g_chlidx;
extern int 					g_dump_chlidx;

#ifdef __cplusplus
	extern "C" {
#endif

//for global api
void  enc_gettime(struct timeval* tv);
U64   enc_gettime_ms();
	
void  enc_set_defscheduler(void);
void  enc_set_rtlscheduler(void);

int   shrmem_init(int isCreate);
void  shrmem_uninit(void);
int   shrmem_dump(int argc, char**argv);
void  shrmem_enc_load();

void  shrmen_enc_eth_load();

int   enc_open_rcvsocket(pENC_ETHIOSET piodesc);
void  enc_add_group(int socket_fd, pENC_ETHIOSET piodesc);
int   enc_open_sndsocket(pENC_ETHIOSET piodesc, const char* netname);

int   enc_open_sndsocket_raw(pENC_ETHIOSET piodesc, pENC_RAW_SOCK_SET prawst);
int   enc_sendto_raw(int fd, pENC_RAW_SOCK_SET prawst, int buflen);

int   enc_is_valid_ip(U32 ip);
int   enc_get_map_ethid(int id);
int   enc_get_unmap_ethid(int id);

void  enc_set_master(int flag);
int   enc_is_master();

void shrmem_enc_load_mst(pENC_DEVSET_MASTER pMaster);
void shrmem_enc_load_slv(pENC_DEVSET_SLAVE pSlave);
void shrmem_enc_load_slv_v2(pENC_DEVSET_SLAVE pSlave);

int enc_file_exist(const char *fname);
void enc_file_write(const char* fname, U8* buf, int buf_len, int is_append);
char* enc_module_folder(void);
void enc_dump_buf(int idx, U8* buf, int buf_len);

#define enc_log(format, ...) \
		_enc_log("[%s %d:%s] " \
		format, \
		__FILE__, __LINE__, __func__, ##__VA_ARGS__ )
void  _enc_log(const char* format,...);

void enc_sig_handler(int sig);
int enc_is_running();

int enc_hex2int(const char s[]);

int hienc_monitor(int argc, char**argv);

// ipaddr mgr
int hienc_set_mstip(const char* ipaddr);
int hienc_set_slv0ip(const char* ipaddr);
const char* hienc_get_priv_netmask();
const char* hienc_get_priv_slv_ipaddr(int subidx);
const char* hienc_get_priv_mst_ipaddr();
U16 hienc_get_priv_mst_port();
U16 hienc_get_priv_slv_port();
int hienc_get_subidx();
void hienc_init_network();
int hienc_net_get_if_ipaddr(const char* ethname, char* buf, int buflen);

#ifdef __cplusplus
}
#endif
#endif
